package com.java.module.chat.util.netty;

import org.apache.commons.lang3.BooleanUtils;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

import java.util.concurrent.*;

/**
 * NettyListener
 * 
 * @author yilabao
 * @date 2021年9月28日
 */
@Component
public class NettyApplication implements ApplicationRunner, DisposableBean {

    @Value("${qchat.netty.enabled}")
    public Boolean enabled;

    @Value("${qchat.netty.host}")
    public String host;

    @Value("${qchat.netty.port}")
    public Integer port;

    @Value("${qchat.netty.path}")
    public String path;

    private NettyServer nettyServer;

    private final ExecutorService nettyServerPool = new ThreadPoolExecutor(1, 1, 0, TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<Runnable>(1024), createThreadFactory(), new ThreadPoolExecutor.AbortPolicy());

    @Override
    public void run(ApplicationArguments args) throws Exception {
        if (BooleanUtils.isTrue(enabled)) {
            nettyServer = new NettyServer(host, port, path);
            // 单开线程启动netty，否则会阻塞主线程
            nettyServerPool.execute(() -> nettyServer.start());
            nettyServerPool.shutdown();
        }
    }

    @Override
    public void destroy() throws Exception {
        if (nettyServer != null) {
            nettyServer.stop();
        }
    }

    private ThreadFactory createThreadFactory() {
        return runnable -> {
            return new Thread(runnable, "netty-qchat-pool-" + port);
        };
    }

}